Skip to content

feat: add hosted WebDriver provider support#948

Open
thymikee wants to merge 22 commits into
mainfrom
codex/cloud-webdriver-provider-runtime
Open

feat: add hosted WebDriver provider support#948
thymikee wants to merge 22 commits into
mainfrom
codex/cloud-webdriver-provider-runtime

Conversation

@thymikee

@thymikee thymikee commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds hosted WebDriver provider support for BrowserStack and AWS Device Farm without adding Limrun to the CLI surface. agent-device connect keeps the existing cloud default, agent-device connect cloud is an explicit alias, connect proxy keeps the direct remote daemon flow, and connect browserstack / connect aws-device-farm now create local provider profiles that allocate hosted sessions on first open.

The provider wiring stays isolated: generated profiles persist non-secret provider selectors, daemon startup composes provider runtimes through the existing request-provider seams, and BrowserStack/AWS session setup delegates to the shared cloud WebDriver runtime. Artifacts remain available through agent-device artifacts --json, including active-session inference and historical provider-session lookup where supported.

This also addresses the code-quality review pass:

  • WebDriver source parsing now reuses the hardened shared XML parser and existing Android bounds parsing instead of bespoke regex XML handling.
  • BrowserStack/AWS provider helpers are consolidated for auth headers, lease-derived labels, URL normalization, capability overrides, and artifact lookup dispatch.
  • Runtime construction and environment-based artifact lookup share one hosted WebDriver provider definition table.
  • The lazy hosted-provider runtime wrapper was removed; each provider creates one shared CloudWebDriverRuntime, and per-lease request/profile setup happens through prepareSession.
  • Daemon startup no longer requires BrowserStack/AWS credentials unless that provider is actually used.
  • Connect profile dispatch is table-driven, shared Metro profile projection is centralized, and AWS flag/env fallback parsing is simplified.
  • Client close/release provider payloads preserve the typed cloud artifact result shape instead of exposing only Record<string, unknown>.
  • The premature public agent-device/cloud-webdriver subpath and leftover source-only facade were removed, so the daemon still ships the runtime chunk without publishing a large unused SDK declaration surface.
  • BrowserStack capability assembly and AWS Device Farm CLI command assembly now have one implementation each.
  • WebDriver scroll gestures now use the remote window rect instead of a hardcoded viewport.
  • The generic artifact callback no longer carries the unused phase mode.

Agents can connect autonomously when credentials are present up front. BrowserStack uses BROWSERSTACK_USERNAME / BROWSERSTACK_ACCESS_KEY; AWS Device Farm uses the AWS CLI credential chain, including CI-provided environment credentials, profiles, or web identity role variables. The Hosted Device Providers docs page captures the CI setup and links to official AWS CLI/OIDC guidance.

Docs/help now give actionable hosted-provider flows and credential guidance across CLI, JavaScript, and MCP: CLI is the canonical bootstrap path, JavaScript can pass provider config directly through the typed client, and MCP is documented as an operational interface after CLI bootstrap rather than a separate provider-connect surface.

Validation

Verified locally with focused CLI/profile/provider tests, docs/help tests, static checks, package build, and fallow audit.

Latest checks:

  • pnpm exec vitest run src/utils/__tests__/args.test.ts src/__tests__/cli-help.test.ts src/__tests__/cloud-connect-profile.test.ts src/__tests__/package-exports.test.ts
  • pnpm exec vitest run src/__tests__/cloud-connect-profile.test.ts src/__tests__/remote-connection.test.ts src/__tests__/default-cloud-artifact-provider.test.ts src/__tests__/package-exports.test.ts test/integration/provider-scenarios/cloud-webdriver-provider-adapters.test.ts test/integration/provider-scenarios/cloud-webdriver-runtime.test.ts
  • pnpm check:quick
  • pnpm build
  • pnpm check:fallow --base origin/main
  • node ./node_modules/oxfmt/bin/oxfmt --write <touched files>
  • git diff --check

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstack.github.io/agent-device/pr-preview/pr-948/

Built to branch gh-pages at 2026-06-30 19:19 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Comment thread src/cloud-webdriver/browserstack.ts Fixed
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
JS raw 1.4 MB 1.4 MB +42.0 kB
JS gzip 450.2 kB 462.1 kB +11.9 kB
npm tarball 549.1 kB 562.3 kB +13.2 kB
npm unpacked 1.9 MB 2.0 MB +48.5 kB

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 27.4 ms 27.8 ms +0.4 ms
CLI --help 47.1 ms 48.6 ms +1.5 ms

Top changed chunks:

Chunk Raw diff Gzip diff
dist/src/7654.js +79.2 kB +25.7 kB
dist/src/9722.js +29.5 kB +8.3 kB
dist/src/cli.js +4.6 kB +1.2 kB
dist/src/2948.js +4.0 kB +1.0 kB
dist/src/cli-help.js +2.4 kB +749 B

@thymikee thymikee force-pushed the codex/cloud-webdriver-provider-runtime branch 6 times, most recently from ad75be7 to b7ec3e3 Compare June 30, 2026 08:07
@thymikee

Copy link
Copy Markdown
Member Author

Reviewed the cloud WebDriver artifact support path.

I traced the shipped command route from CLI/typed client input through command projection, daemon lease routing, active-session lease inference, provider runtime artifact lookup, and close/disconnect release payloads. The important paths are covered by tests: active-session artifacts before release, handled-unavailable artifact lookup, provider release payloads, BrowserStack/AWS artifact mapping, CLI text/JSON output, command descriptor routing, and package exports.

Checks are green, and the PR body includes live verification for existing BrowserStack and AWS Device Farm sessions without opening new cloud minutes. I do not see remaining actionable blockers; ready for human review/merge judgment.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jun 30, 2026
@thymikee thymikee changed the title feat: add cloud WebDriver artifact support feat: add hosted WebDriver provider support Jun 30, 2026
Comment thread src/cloud-webdriver/webdriver-utils.ts Fixed
@thymikee thymikee force-pushed the codex/cloud-webdriver-provider-runtime branch 2 times, most recently from d99e4c6 to f756370 Compare June 30, 2026 12:55
@thymikee

Copy link
Copy Markdown
Member Author

Correction: my previous comment was mangled by shell quoting. The blocker is in src/cli/commands/connection.ts line 318 on the PR head. disconnect reads the active generated connection state, but then calls client.sessions.close with only shutdown. The real client resolves that to the default session when no session override is present, so agent-device disconnect without a session can close default while releasing and removing local state for the generated active session such as adc-android. That can strand the actual provider-backed daemon session/runtime until lease expiry or manual cleanup. Please pass the resolved connected session into close, for example client.sessions.close({ session: connectedSession, shutdown: flags.shutdown }), and add an assertion that active-state disconnect closes the active session rather than default.

@thymikee thymikee removed the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jun 30, 2026
@thymikee thymikee force-pushed the codex/cloud-webdriver-provider-runtime branch from 704a764 to 71c7b6a Compare June 30, 2026 16:49
@thymikee thymikee force-pushed the codex/cloud-webdriver-provider-runtime branch from 5d0732e to 6563089 Compare June 30, 2026 17:30
@thymikee

Copy link
Copy Markdown
Member Author

Re-checked current clean head 6563089 after the prior disconnect blocker.

The blocker is addressed: disconnect now closes the resolved active generated session via client.sessions.close({ session: connectedSession, shutdown: flags.shutdown }) before cleanup/release, and the built-CLI provider smoke test asserts the close RPC targets the adc-* active session rather than default before release and state removal. Checks are green.

I did not rerun live BrowserStack or AWS minutes in this monitor pass; the remaining provider behavior is covered by the PR tests and should be judged with that residual risk. I do not see an actionable blocker; ready for maintainer review.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jun 30, 2026
@thymikee

Copy link
Copy Markdown
Member Author

Re-checked current clean head bd4cbb4. The delta from the previously reviewed 6563089 head is focused on making hosted WebDriver sessions launchable:

  • deferred provider materialization now forwards platform/device/provider fields into lease allocation, with coverage for BrowserStack profile fields
  • public lease allocation options now include selection fields through AgentDeviceSelectionOptions
  • WebDriver activate/terminate now prefer Appium device endpoints and fall back to mobile scripts
  • lease scope projection now preserves provider/client/device identifiers

Checks are green. This does not reopen the prior disconnect-session blocker, and I do not see a new actionable blocker; the existing ready-for-human label is still appropriate.

@thymikee

Copy link
Copy Markdown
Member Author

PR #948 is now conflicting against current main after #968 merged, so I removed ready-for-human. Please rebase/resolve conflicts and rerun checks; this needs a fresh review pass on the resolved head before the readiness label is restored.

@thymikee thymikee removed the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants